<template>
  <view class="connection-item">
    <image class="connection-img" src="https://app5.shuguostar.cn/imgs/images/demo/bg.png" />

    <canvas id="Canvas" class="connection-canvas" canvas-id="Canvas" :disable-scroll="true" />

    <view class="connection-content flex flex-col justify-between" @touchstart="handleStart" @touchend="handleEnd" @touchmove="handleMove">
      <view class="content-top flex justify-between">
        <image v-for="item in 4" :key="`top-${item}`" class="connection-top" :class="[`connection-top-${item}`]" :src="`https://app5.shuguostar.cn/imgs/images/demo/connection_top_${item}.png`" />
      </view>
      <view class="content-bottom flex justify-between">
        <image v-for="item in 8" :key="`bottom-${item}`" class="connection-bottom" :src="`https://app5.shuguostar.cn/imgs/images/demo/connection_bottom_${item}.png`" />
      </view>
    </view>
  </view>
</template>

<script setup lang="ts" name="ConnectionItem">
import { getCurrentInstance } from 'vue';
import type { Question } from '@/pages/views/demo/type';

const props = defineProps({
  question: {
    type: Object as () => Question,
    default: () => {},
  },
});

const instance = getCurrentInstance() as any;
const ctx = ref();

const answerTextList = ref<Array<string>>([]);
const answerList = ref<Array<{ index: number; text: string }>>([]);
const parentInfo: { left: number; top: number } = { top: 0, left: 0 };
let topItemInfo: Array<{ width: number; height: number; x1: number; y1: number; x2: number; y2: number; x: number; y: number }> = [];
let bottomItemInfo: Array<{ width: number; height: number; x1: number; y1: number; x2: number; y2: number; x: number; y: number }> = [];
const chooseArray: Array<{ type: string; top: number; bottom: number }> = [];
const path = ref<Array<{ x1: number; y1: number; x2: number; y2: number }>>([]);
const x1 = ref<number>(0); // 起始点x坐标
const y1 = ref<number>(0); // 起始点y坐标
const x2 = ref<number>(0); // 结束点x坐标
const y2 = ref<number>(0); // 结束点y坐标

const drawLine = (fromX?: number, fromY?: number, toX?: number, toY?: number) => {
  ctx.value.beginPath();
  // 恢复已经连好的线
  path.value.forEach((item) => {
    ctx.value.moveTo(item.x1 - parentInfo.left, item.y1 - parentInfo.top);
    ctx.value.lineTo(item.x2 - parentInfo.left, item.y2 - parentInfo.top);
  });
  if (fromX && fromY && toX && toY) {
    ctx.value.moveTo(fromX - parentInfo.left, fromY - parentInfo.top);
    ctx.value.lineTo(toX - parentInfo.left, toY - parentInfo.top);
  }
  ctx.value.setStrokeStyle('#7B4F21');
  ctx.value.setLineWidth(2);
  ctx.value.stroke();
  ctx.value.draw();
};

const isRange = (x: number, y: number, type: number) => {
  let finalX, finalY, topIndex, bottomIndex, pos;
  for (let i = 0; i < topItemInfo.length; i++) {
    const item = topItemInfo[i];
    if (item.x1 < x && x < item.x2 && item.y1 < y && y < item.y2) {
      finalX = item.x;
      finalY = item.y;
      topIndex = i + 1;
      pos = 'top';
    }
  }

  for (let i = 0; i < bottomItemInfo.length; i++) {
    const item = bottomItemInfo[i];
    if (item.x1 < x && x < item.x2 && item.y1 < y && y < item.y2) {
      finalX = item.x;
      finalY = item.y;
      bottomIndex = i + 1;
      pos = 'bottom';
    }
  }

  if (!finalX) {
    x1.value = 0;
    y1.value = 0;
    x2.value = 0;
    y2.value = 0;
    if (type === 2)
      chooseArray.pop();
    return;
  }

  const index = topIndex || bottomIndex || 0;
  if (type === 1) {
    x1.value = finalX;
    y1.value = finalY!;
    chooseArray.push({
      type: pos || '',
      top: topIndex || 0,
      bottom: bottomIndex || 0,
    });
  }
  else {
    const startPoint = chooseArray[chooseArray.length - 1];
    if (startPoint.type !== pos) {
      x2.value = finalX;
      y2.value = finalY!;
      pos === 'top' ? startPoint.top = index : startPoint.bottom = index;
    }
    if (startPoint.type === pos) {
      chooseArray.pop();
    }
  }
};

const handleStart = (e: any) => {
  isRange(Number(e.changedTouches[0].clientX), Number(e.changedTouches[0].clientY), 1);
};

const handleEnd = (e: any) => {
  isRange(Number(e.changedTouches[0].clientX), Number(e.changedTouches[0].clientY), 2);
  if (x2.value) {
    path.value.push({
      x1: x1.value,
      y1: y1.value,
      x2: x2.value,
      y2: y2.value,
    });
  }
  drawLine();
  x1.value = 0;
  y1.value = 0;
  x2.value = 0;
  y2.value = 0;
};

const handleMove = (e: any) => {
  if (!x1.value)
    return;

  const clientX = e.changedTouches[0].clientX;
  const clientY = e.changedTouches[0].clientY;
  drawLine(x1.value, y1.value, clientX, clientY);
};

const isPlay = ref<boolean>(false);
const connection = 'https://app5.shuguostar.cn/imgs/bookVido/audio/connection.mp3';
let innerAudioContext: any;
const playAudio = () => {
  innerAudioContext = uni.createInnerAudioContext();
  innerAudioContext.autoplay = true;
  innerAudioContext.src = connection;
  innerAudioContext.onPlay(() => {
    isPlay.value = true;
  });
  innerAudioContext.onEnded(() => {
    isPlay.value = false;
  });
};

const pauseAudio = () => {
  innerAudioContext?.destroy();
  innerAudioContext = null;
};

onReady(() => {
  playAudio();
  ctx.value = uni.createCanvasContext('Canvas', instance);
  uni.createSelectorQuery().in(instance).selectAll('.connection-top').boundingClientRect((rect: any) => {
    topItemInfo = rect.map((item: any) => {
      return {
        width: item.width,
        height: item.height,
        x1: item.left,
        y1: item.top,
        x2: item.left + item.width,
        y2: item.top + item.height,
        x: item.left + item.width / 2,
        y: item.top + item.height / 2,
      };
    });
  }).exec();
  uni.createSelectorQuery().in(instance).selectAll('.connection-bottom').boundingClientRect((rect: any) => {
    bottomItemInfo = rect.map((item: any) => {
      return {
        width: item.width,
        height: item.height,
        x1: item.left,
        y1: item.top,
        x2: item.left + item.width,
        y2: item.top + item.height,
        x: item.left + item.width / 2,
        y: item.top + item.height / 2,
      };
    });
  }).exec();

  uni.createSelectorQuery().in(instance).select('.connection-content').boundingClientRect((rect: any) => {
    parentInfo.top = rect.top;
    parentInfo.left = rect.left;
  }).exec();
});

watch(() => props.question?.id, () => {
  answerTextList.value = [];
  // answerList.value = [];
}, { deep: true });

defineExpose({
  answerList,
  answerTextList,
  pauseAudio,
});
</script>

<style lang="scss" scoped>
@function tovmin($rpx){//$rpx为需要转换的字号
  @return #{calc($rpx * 100 / 750)}vmin;
}

.connection-item {
  position: relative;
  width: tovmin(1060);
  height: tovmin(540);
  margin: tovmin(40);
  padding: tovmin(10);
  border-radius: tovmin(12);
  background: #fff;

  .connection-img {
    position: absolute;
    top: tovmin(10);
    left: tovmin(10);
    width: tovmin(1040);
    height: tovmin(520);
    border-radius: tovmin(12);
  }

  .connection-canvas {
    position: absolute;
    top: tovmin(10);
    left: tovmin(10);
    width: tovmin(1040);
    height: tovmin(520);
    border-radius: tovmin(12);
    z-index: 8;
  }

  .connection-content {
    position: relative;
    width: 100%;
    height: tovmin(520);
    padding: tovmin(50) tovmin(55);
    z-index: 9;

    .content-top {
      padding: tovmin(0) tovmin(36);

      .connection-top {
        width: tovmin(116);
        height: tovmin(127);
      }
    }

    .content-bottom {
      .connection-bottom {
        width: tovmin(97);
        height: tovmin(92);
      }
    }
  }
}
</style>
